package org.datascooter.test;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;

import org.datascooter.impl.DataSnip;
import org.datascooter.impl.DataSnipFactory;
import org.datascooter.impl.Snip;
import org.datascooter.inface.IDataManager;
import org.datascooter.utils.policy.Constraint;
import org.datascooter.utils.policy.SnipType;

public class ChangeAssistant {

	public void flushChanges(String fileName, Date fromDate, IDataManager srcManager, IDataManager destManager) throws IOException {
		FileOutputStream outputStream = new FileOutputStream(fileName);
		try {
			outputStream.write(encodePackage(buildChangePackage(fromDate, srcManager, destManager)));
			outputStream.flush();
		} finally {
			outputStream.close();
		}
	}

	public void restoreChanges(String fileName, IDataManager destManager) throws IOException, ClassNotFoundException {
		FileInputStream inputStream = null;
		try {
			inputStream = new FileInputStream(fileName);
			ByteBuffer byteBuffer = ByteBuffer.allocate(5000);
			byte[] buffer = new byte[5000];
			while (inputStream.read(buffer) > 0) {
				byteBuffer.put(buffer);
				buffer = new byte[5000];
			}
			Snip decodedPackage = (Snip) decodePackage(byteBuffer.array());
			System.out.println("------------decodedPackage---------" + decodedPackage.getFetch().length);
			destManager.execute(decodedPackage);
		} finally {
			inputStream.close();
		}
	}

	public Snip buildChangePackage(Date fromDate, IDataManager srcManager, IDataManager destManager) {
		DataSnip where = DataSnipFactory.select(DataSnip.class).where("created", fromDate, Constraint.GREATER_THAN_OR_EQUAL);
		List<DataSnip> list = srcManager.list(where);
		List<Snip> snipList = new ArrayList<Snip>();
		System.out.println("-------------found changes: ---------" + snipList.size());
		for (DataSnip dataSnip : list) {
			snipList.add(destManager.getSnip(dataSnip));
		}
		return new Snip(null, SnipType.GROUP, null, null, null, snipList.toArray(new Snip[snipList.size()]), -1, null);
	}

	public byte[] encodePackage(Object object) throws IOException {
		ByteArrayOutputStream bout = new ByteArrayOutputStream();
		GZIPOutputStream zout = new GZIPOutputStream(bout);
		ObjectOutputStream oout = new ObjectOutputStream(zout);
		try {
			oout.writeObject(object);
			zout.finish();
			return bout.toByteArray();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			zout.close();
			oout.close();
		}
		return null;
	}

	public Object decodePackage(byte[] array) throws IOException, ClassNotFoundException {
		try {
			ObjectInputStream oin = new ObjectInputStream(new GZIPInputStream(new ByteArrayInputStream(array)));
			try {
				return oin.readObject();
			} finally {
				if (oin != null)
					oin.close();
			}
		} catch (Exception e) {
			e.printStackTrace();
			throw new RuntimeException(e);
		}
	}
}
